<?php



/**
 * Radcodes - SocialEngine Module
 *
 * @category   Application_Extensions
 * @package    Game
 * @copyright  Copyright (c) 2009-2010 Radcodes LLC (http://www.radcodes.com)
 * @license    http://www.radcodes.com/license/
 * @version    $Id$
 * @author     Vincent Van <vincent@radcodes.com>
 */
 
 
 
class Game_Model_Game extends Core_Model_Item_Abstract implements Countable
{
  // Properties
  protected $_owner_type = 'user';

  protected $_searchTriggers = array('search', 'title', 'description');

  protected $_modifiedTriggers = array('search', 'title', 'description', 'target', 'statement', 'keywords', 'rating_goal', 'deadline');
  
  protected $category;
  
  const STATUS_PUBLISHED = 'published';
  const STATUS_PENDING = 'pending';
  const STATUS_DISABLED = 'disabled';
  
  const CONTENT_RATING_EVERYONE = 'everyone';
  const CONTENT_RATING_TEEN = 'teen';
  const CONTENT_RATING_MATURE = 'mature';  
  
  /**
   * Gets an absolute URL to the page to view this item
   *
   * @return string
   */
  public function getHref($params = array())
  {
    if (isset($params['action']))
    {
      $params = array_merge(array(
        'route' => 'game_specific',
        'reset' => true,
        'game_id' => $this->game_id,
      ), $params);
    }
    else
    {
      $params = array_merge(array(
        'route' => 'game_profile',
        'reset' => true,
        'game_id' => $this->game_id,
        'slug' => $this->getSlug(),
      ), $params);
    } 

    $route = $params['route'];
    $reset = $params['reset'];
    unset($params['route']);
    unset($params['reset']);
    return Zend_Controller_Front::getInstance()->getRouter()
      ->assemble($params, $route, $reset);
  }


  public function getCategory()
  {
    if (!($this->category instanceof Game_Model_Category) || $this->category->getIdentity() != $this->category_id)
    {
      $category = Engine_Api::_()->game()->getCategory($this->category_id);
      if (!($category instanceof Game_Model_Category))
      {
        $category = new Game_Model_Category(array());
      }
      $this->category = $category;
    }

    return $this->category;
  }
  
  
  // Interfaces
  /**
   * Gets a proxy object for the comment handler
   *
   * @return Engine_ProxyObject
   **/
  public function comments()
  {
    return new Engine_ProxyObject($this, Engine_Api::_()->getDbtable('comments', 'core'));
  }

  /**
   * Gets a proxy object for the like handler
   *
   * @return Engine_ProxyObject
   **/
  public function likes()
  {
    return new Engine_ProxyObject($this, Engine_Api::_()->getDbtable('likes', 'core'));
  }

  /**
   * Gets a proxy object for the tags handler
   *
   * @return Engine_ProxyObject
   **/
  public function tags()
  {
    return new Engine_ProxyObject($this, Engine_Api::_()->getDbtable('tags', 'core'));
  }
  
  /**
   * Gets a proxy object for the rating handler
   *
   * @return Engine_ProxyObject | Review_Model_DbTable_Votes
   **/  
  public function ratings()
  {
    return new Engine_ProxyObject($this, Engine_Api::_()->getDbtable('ratings', 'game'));
  }
  
  /**
   * Gets a proxy object for the rating handler
   *
   * @return Review_Model_DbTable_Favorites | Engine_ProxyObject
   **/  
  public function favorites()
  {
    return new Engine_ProxyObject($this, Engine_Api::_()->getDbtable('favorites', 'game'));
  }
  
  /**
   * Gets a proxy object for the score handler
   *
   * @return Review_Model_DbTable_Scores
   **/  
  public function scores()
  {
    return new Engine_ProxyObject($this, Engine_Api::_()->getDbtable('scores', 'game'));
  }
  
  public function removeSwf()
  {
    if (empty($this->swf_file_id))
    {
      return;
    }
    
    $types = array(null);
    foreach ($types as $type)
    {
      $file = Engine_Api::_()->getApi('storage', 'storage')->get($this->swf_file_id, $type);
      if ($file)
      {
        $file->remove();
      } 
    }
    
    $this->swf_file_id = 0;
  }  
  
  public function setSwf($swf)
  {
    if( $swf instanceof Zend_Form_Element_File ) {
      $file = $swf->getFileName();
      $fileName = $file;
    } else if( $swf instanceof Storage_Model_File ) {
      $file = $swf->temporary();
      $fileName = $swf->name;
    } else if( $swf instanceof Core_Model_Item_Abstract && !empty($swf->swf_file_id) ) {
      $tmpRow = Engine_Api::_()->getItem('storage_file', $swf->swf_file_id);
      $file = $tmpRow->temporary();
      $fileName = $tmpRow->name;
    } else if( is_array($swf) && !empty($swf['tmp_name']) ) {
      $file = $swf['tmp_name'];
      $fileName = $swf['name'];
    } else if( is_string($swf) && file_exists($swf) ) {
      $file = $swf;
      $fileName = $swf;
    } else {
      throw new Game_Model_Exception('invalid argument passed to setSwf');
    }

    if( !$fileName ) {
      $fileName = $file;
    }

    $name = basename($file);
    $extension = ltrim(strrchr($fileName, '.'), '.');
    $base = rtrim(substr(basename($fileName), 0, strrpos(basename($fileName), '.')), '.');
    $path = APPLICATION_PATH . DIRECTORY_SEPARATOR . 'temporary';
    $params = array(
      'parent_type' => $this->getType(),
      'parent_id' => $this->getIdentity(),
      'user_id' => $this->user_id,
      'name' => $fileName,
    );

    //Engine_Api::_()->getApi('debug','radcodes')->log($swf, "swf");
    //Engine_Api::_()->getApi('debug','radcodes')->log($params, "file=$file fileName=$fileName name=$name ext=$extension base=$base path=$path params=");
    
    // Save
    $filesTable = Engine_Api::_()->getDbtable('files', 'storage');

    // Resize image (main)
    $mainPath = $path . DIRECTORY_SEPARATOR . $base . '.' . $extension;
    $mainPath = $file;
    /*
    if( !move_uploaded_file($file, $mainPath) ) {    
      throw new Game_Model_Exception("Unable to move file to upload directory. From=$file Destination=$mainPath");
    }
    */
    // Store
    try {
      $iMain = $filesTable->createFile($mainPath, $params);
    } catch( Exception $e ) {
      // Remove temp files
      @unlink($mainPath);
      // Throw
      if( $e->getCode() == Storage_Model_DbTable_Files::SPACE_LIMIT_REACHED_CODE ) {
        throw new Game_Model_Exception($e->getMessage(), $e->getCode());
      } else {
        throw $e;
      }
    }
    
    // Remove temp files
    @unlink($mainPath);

    // Update row
    $this->swf_file_id = $iMain->file_id;
    $this->save();

    // Delete the old file?
    try {
	    if( !empty($tmpRow) ) {
	      $tmpRow->delete();
	    }
    } catch( Exception $e ) {
    	// silence
    }
    
    return $this;
  }
  
  public function setPhoto($photo)
  {  
    if( $photo instanceof Zend_Form_Element_File ) {
      $file = $photo->getFileName();
    } else if( $photo instanceof Storage_Model_File ) {
      $file = $photo->temporary();
    } else if( $photo instanceof Core_Model_Item_Abstract && !empty($photo->file_id) ) {
      $file = Engine_Api::_()->getItem('storage_file', $photo->file_id)->temporary();
    } else if( is_array($photo) && !empty($photo['tmp_name']) ) {
      $file = $photo['tmp_name'];
    } else if( is_string($photo) && file_exists($photo) ) {
      $file = $photo;
    } else {
      throw new Game_Model_Exception('invalid argument passed to setPhoto');
    }

    $name = basename($file);
    $path = APPLICATION_PATH . DIRECTORY_SEPARATOR . 'temporary';
    $params = array(
      'parent_type' => $this->getType(),
      'parent_id' => $this->getIdentity(),
      'user_id' => $this->user_id,
    );

    // Save
    $storage = Engine_Api::_()->storage();

    // Resize image (main)
    $image = Engine_Image::factory();
    $image->open($file)
      ->resize(720, 720)
      ->write($path.'/m_'.$name)
      ->destroy();

    // Resize image (profile)
    $image = Engine_Image::factory();
    $image->open($file)
      ->resize(200, 400)
      ->write($path.'/p_'.$name)
      ->destroy();

    // Resize image (normal)
    $image = Engine_Image::factory();
    $image->open($file)
      ->resize(140, 160)
      ->write($path.'/in_'.$name)
      ->destroy();

    // Resize image (icon)
    $image = Engine_Image::factory();
    $image->open($file);

    $size = min($image->height, $image->width);
    $x = ($image->width - $size) / 2;
    $y = ($image->height - $size) / 2;

    $image->resample($x, $y, $size, $size, 48, 48)
      ->write($path.'/is_'.$name)
      ->destroy();
      
    // Store
    $iMain = $storage->create($path.'/m_'.$name, $params);
    $iProfile = $storage->create($path.'/p_'.$name, $params);
    $iIconNormal = $storage->create($path.'/in_'.$name, $params);
    $iSquare = $storage->create($path.'/is_'.$name, $params);
    
    $iMain->bridge($iProfile, 'thumb.profile');
    $iMain->bridge($iIconNormal, 'thumb.normal');
    $iMain->bridge($iSquare, 'thumb.icon');
    
    // Remove temp files
    @unlink($path.'/p_'.$name);
    @unlink($path.'/m_'.$name);
    @unlink($path.'/in_'.$name);
    @unlink($path.'/is_'.$name);
    
    // Update row
    $this->photo_id = $iMain->file_id;
    $this->save();
    
    if( is_string($photo) && file_exists($photo) ) {
      @unlink($photo);
    }    
    
    return $this;  
  }
  
  public function removePhoto()
  {
    if (empty($this->photo_id))
    {
      return;
    }
    
    $types = array(null, 'thumb.profile', 'thumb.normal', 'thumb.icon');
    foreach ($types as $type)
    {
      $file = Engine_Api::_()->getApi('storage', 'storage')->get($this->photo_id, $type);
      if ($file)
      {
        $file->remove();
      } 
    }
    
    $this->photo_id = 0;
  }
  
  
  protected function _delete()
  {
    if( $this->_disableHooks ) return;

    // Delete all field values
    $values = Engine_Api::_()->fields()->getFieldsValues($this);
    foreach ($values as $value)
    {
      $value->delete();
    }
    
    // Delete search row
    $search = Engine_Api::_()->fields()->getFieldsSearch($this);
    if ($search)
    {
      $search->delete();
    }

    // Delete all favorites
    $favoriteTable = Engine_Api::_()->getItemTable('game_favorite');
    $favoriteSelect = $favoriteTable->select()->where('game_id = ?', $this->getIdentity());
    foreach( $favoriteTable->fetchAll($favoriteSelect) as $favorite ) {
      $favorite->delete();
    }    
    
    // Delete all scores
    $scoreTable = Engine_Api::_()->getItemTable('game_score');
    $scoreSelect = $scoreTable->select()->where('game_id = ?', $this->getIdentity());
    foreach( $scoreTable->fetchAll($scoreSelect) as $score ) {
      $score->delete();
    }     
    
    parent::_delete();
  }

  protected function _postDelete()
  {
    $this->removePhoto();
    $this->removeSwf();
    
    parent::_postDelete();
  }
  
  public function count()
  {
    $ratingTable = Engine_Api::_()->getItemTable('game_rating');
    return $ratingTable->select()
        ->from($ratingTable, new Zend_Db_Expr('COUNT(rating_id)'))
        ->where('game_id = ?', $this->getIdentity())
        ->limit(1)
        ->query()
        ->fetchColumn();
  }  

  
  //////////////
  
  public function getPhotoUrl($type = null)
  {
    $photo_url = parent::getPhotoUrl($type);
    
    if (!$photo_url) {
      $photo_url = $this->thumbnail_url;
    }
    
    return $photo_url;
  }  
  
  public function getSwfFileUrl()
  {
    if( empty($this->swf_file_id) ) {
      return null;
    }

    $file = Engine_Api::_()->getItemTable('storage_file')->getFile($this->swf_file_id, null);
    if( !$file ) {
      return null;
    }
    
    return $file->map();    
  }
  
  public function getSwfUrl()
  {
    $swf_url = $this->getSwfFileUrl();
    
    if (!$swf_url) {
      $swf_url = $this->swf_url;
    }
    
    return $swf_url;
  }
  
  public function getContentRating()
  {
    $options = Game_Form_Helper::getContentRatings();
    return (isset($options[$this->content_rating])) ? $options[$this->content_rating] : 'Everyone';
  }
  
  public function getDistributorType()
  {
    $options = Game_Form_Helper::getDistributorTypes();
    return (isset($options[$this->distributor_type])) ? $options[$this->distributor_type] : 'Manual';
  }
  
  
  public function isPublished()
  {
    return $this->status == self::STATUS_PUBLISHED;
  }
  
  
  public function downloadSwf()
  {
    if ($this->swf_url && Zend_Uri::check($this->swf_url))
    {
      $game_file = Engine_Api::_()->game()->downloadFile($this->swf_url);
      $this->setSwf($game_file);
      return true;
    }
    return false;
  }
  
  
  public function downloadPhoto()
  {
    if ($this->thumbnail_url && Zend_Uri::check($this->thumbnail_url))
    {
      $photo_file = Engine_Api::_()->game()->downloadFile($this->thumbnail_url);
      $this->setPhoto($photo_file);
      return true;
    }
    
    return false;
  }
  
}